/*
 *
 *
 */

#ifndef GKT_USER_DEFINES_H
#define GKT_USER_DEFINES_H

#include "gkt_user_fingerprint.h"
#include "gkt_user_password.h"
#include "gkt_user_card.h"
#include "gkt_user_face_id.h"

#define GKT_USER_ADMIN_MAXNUMS	\
	(GKT_USER_FINGERPRINT_ADMIN_MAXNUMS \
		+ GKT_USER_PASSWORD_ADMIN_MAXNUMS \
		+ GKT_USER_FACE_ID_ADMIN_MAXNUMS \
		+ GKT_USER_CARD_ADMIN_MAXNUMS)
#define GKT_USER_NORMAL_MAXNUMS	\
	(GKT_USER_FINGERPRINT_NORMAL_MAXNUMS \
		+ GKT_USER_PASSWORD_NORMAL_MAXNUMS \
		+ GKT_USER_FACE_ID_NORMAL_MAXNUMS \
		+ GKT_USER_CARD_NORMAL_MAXNUMS)
#define GKT_USER_GUEST_MAXNUMS	\
	(GKT_USER_FINGERPRINT_GUEST_MAXNUMS \
		+ GKT_USER_PASSWORD_GUEST_MAXNUMS \
		+ GKT_USER_FACE_ID_GUEST_MAXNUMS \
		+ GKT_USER_CARD_GUEST_MAXNUMS)

#define GKT_USER_MAXNUMS	\
	(GKT_USER_ADMIN_MAXNUMS \
		+ GKT_USER_NORMAL_MAXNUMS \
		+ GKT_USER_GUEST_MAXNUMS)

/* user id fields */
#define GKT_USER_INDEX_BITS	16
#define GKT_USER_TYPE_BITS	4
#define GKT_USER_TYPE_EXTEND_BITS	4
#define GKT_USER_AUTH_BITS	4
#define GKT_USER_THREATEN_BITS	1
#define GKT_USER_TAG_BITS	2

#define GKT_USER_INDEX_SHIFT	0
#define GKT_USER_TYPE_SHIFT	\
	(GKT_USER_INDEX_SHIFT + GKT_USER_INDEX_BITS)
#define GKT_USER_TYPE_EXTEND_SHIFT	\
	(GKT_USER_TYPE_SHIFT + GKT_USER_TYPE_BITS)
#define GKT_USER_AUTH_SHIFT	\
	(GKT_USER_TYPE_EXTEND_SHIFT + GKT_USER_TYPE_EXTEND_BITS)
#define GKT_USER_THREATEN_SHIFT	\
	(GKT_USER_AUTH_SHIFT + GKT_USER_AUTH_BITS)
#define GKT_USER_TAG_SHIFT	\
	(GKT_USER_THREATEN_SHIFT + GKT_USER_THREATEN_BITS)

#define GKT_USER_ID_TAG	1

#define GKT_USER_FIELD_MASK(FIELD_NAME)	\
	(((1U << GKT_USER_##FIELD_NAME##_BITS) - 1) \
		<< GKT_USER_##FIELD_NAME##_SHIFT)
#define GKT_USER_FIELD(value, FIELD_NAME)	\
	(((uint32_t)(value) << GKT_USER_##FIELD_NAME##_SHIFT) \
		& GKT_USER_FIELD_MASK(FIELD_NAME))

#define GKT_USER_ID_BUILD_FULL(authority, threaten, type, type_extend, index)	\
	((GKT_USER_ID_TAG << GKT_USER_TAG_SHIFT)  \
		| GKT_USER_FIELD(authority, AUTH) \
		| GKT_USER_FIELD(threaten, THREATEN) \
		| GKT_USER_FIELD(type, TYPE) \
		| GKT_USER_FIELD(type_extend, TYPE_EXTEND) \
		| GKT_USER_FIELD(index, INDEX))
#define GKT_USER_ID_BUILD(authority, threaten, type, index)	\
	GKT_USER_ID_BUILD_FULL(authority, threaten, type, 0, index)

#define GKT_USER_FIELD_VALUE(user_id, FIELD_NAME)	\
	(((user_id) & GKT_USER_FIELD_MASK(FIELD_NAME)) \
		>> GKT_USER_##FIELD_NAME##_SHIFT)
#define GKT_USER_INDEX(user_id)	GKT_USER_FIELD_VALUE(user_id, INDEX)
#define GKT_USER_TYPE_EXTEND(user_id)	GKT_USER_FIELD_VALUE(user_id, TYPE_EXTEND)
#define GKT_USER_TYPE(user_id)	GKT_USER_FIELD_VALUE(user_id, TYPE)
#define GKT_USER_AUTH(user_id)	GKT_USER_FIELD_VALUE(user_id, AUTH)
#define GKT_USER_THREATENING(user_id)	GKT_USER_FIELD_VALUE(user_id, THREATEN)
#define GKT_USER_TAG(user_id)	GKT_USER_FIELD_VALUE(user_id, TAG)


/* user index range */
#define GKT_USER_INDEX_MIN	1
#if defined(GKT_CONFIG_USER_INDEX_MAX) \
	&& (GKT_CONFIG_USER_INDEX_MAX > GKT_USER_MAXNUMS)
#define GKT_USER_INDEX_MAX	GKT_CONFIG_USER_INDEX_MAX
#else
#define GKT_USER_INDEX_MAX	GKT_USER_MAXNUMS
#endif

#if (GKT_USER_INDEX_MAX < 100)
#define GKT_USER_INDEX_DIGITS	2
#elif (GKT_USER_INDEX_MAX < 1000)
#define GKT_USER_INDEX_DIGITS	3
#else
#error "GKT_USER_INDEX_MAX OVERFLOW!"
#endif

#endif	/* GKT_USER_DEFINES_H */

